package com.hh.service.impl;

import com.hh.mapper.CarouselMapper;
import com.hh.pojo.*;
import com.hh.service.CarouselService;
import com.hh.utils.FileTool;
import com.hh.utils.ServiceTool;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.io.File;
import java.io.IOException;
import java.util.*;


@Service
public class CarouselServiceImpl implements CarouselService {
    @Resource
    private CarouselMapper carouselMapper;

    /*这里接收到的 carouselPost 对象 只初始化了 postId 和 describe 两个字段，其他都为 0（基本数据类型） 或 null（对象）*/
    @Override
    public MessageModel addCarousel(CarouselPost carouselPost, MultipartFile img, String imgSavePath) {
        MessageModel messageModel = new MessageModel(200, "添加成功！");
        File filePath = new File(imgSavePath);  //文件上传路径（不包括文件名）
        String saveName;  /*文件保存名*/
        String separator = File.separator; //定义分隔符
        int i;  /*文件名 小数点位置*/
        int newId; //新滚动帖的id编号
        String fileType;  /*文件类型 包括.*/

        try {
            // 将图片文件以新滚动帖编号命名（id） 保存     将文件保存到服务器
            if (img.getSize() != 0){
                i = Objects.requireNonNull(img.getOriginalFilename()).lastIndexOf('.');
                fileType = img.getOriginalFilename().substring(i);  /*包括.*/
                fileType = fileType.toLowerCase(); //一律转小写
                newId = carouselMapper.getNextVal();
                saveName = newId + fileType;

                carouselPost.setImages(saveName);
                img.transferTo(new File(filePath + separator + saveName));
            }
            //将滚动帖记录写入数据库
            if (carouselMapper.addCarouselPost(carouselPost) < 1){
                messageModel.setResult_code(300);
                messageModel.setMsg("添加失败，（数据库插入失败。）");
            }
        }catch (IOException e){
            messageModel.setResult_code(408);
            messageModel.setMsg("文件写入发生异常。");
            e.printStackTrace();
        }
        catch (Exception e){
            messageModel.setResult_code(303);
            messageModel.setMsg("数据库插入（贴吧）发生异常。");
            e.printStackTrace();
        }
        return messageModel;
    }

    @Override
    public Map<String, Object> getCarouselListByMap(Map<String, Object> map) {
        try {
            return ServiceTool.getList(carouselMapper.getCrsListByMap(map));
        }catch (Exception e){  /*数据库查询发生异常*/
            e.printStackTrace();
            return ServiceTool.getListWrong();
        }
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED,isolation = Isolation.DEFAULT,timeout=36000,rollbackFor=Exception.class)
    public MessageModel updateCrsListOrders(CarouselPost[] list) {
        MessageModel rs = new MessageModel(200, "顺序保存成功！");
        List<CarouselPost> crsToUpdate = new LinkedList<>(); // 要修改序号的滚动帖
        HashMap<String, Object> map; // mapper 层参数

        // 判断是否为空
        if (list == null || list.length == 0){
            rs.setMsg("顺序暂无变化，无需调整。");
            rs.setResult_code(322);
        }else {
            try {
                // 取出 要调整的元素（showOrder 和 位置index+1  不一致）
                for (int i = 0; i < list.length; i++) {
                    if (list[i].getShowOrder() != (i+1)){
                        list[i].setShowOrder(i+1);
                        crsToUpdate.add(list[i]);
                    }
                }

                // 判断是否有数据变更
                if (crsToUpdate.size() > 0){
                    // 变更数据（修改数据库记录）
                    map = new HashMap<>();
                    for (CarouselPost crs : crsToUpdate) {
                        map.put("showOrder", crs.getShowOrder()); // 相同的键，默认后面会覆盖前面的
                        map.put("id", crs.getId());
                        if (carouselMapper.updateCarousel(map) < 1){
                            rs.setResult_code(300);
                            rs.setMsg("调整失败，（数据库更新失败。）");
                        }
                    }
                }else {
                    rs.setMsg("顺序暂无变化，无需调整。");
                    rs.setResult_code(322);
                }
            }catch (Exception e){
                rs.setResult_code(303);
                rs.setMsg("数据库更新（滚动帖）发生异常。");
                e.printStackTrace();
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();  //由于手动catch了异常， 此处需要手动进行事务回滚
            }
        }

        return rs;
    }


    @Override
    public Map<String, Object> getSimpleCrsById(int id) {
        MessageModel rs = new MessageModel(200, "滚动帖信息查询成功！"); // 查询结果
        Map<String, Object> rsMap = new HashMap<>(); // 结果 map

        try {
            CarouselPost simpleCrsById = carouselMapper.getSimpleCrsById(id);

            // 根据id 查询不到结果
            if (simpleCrsById == null){
                rs.setResult_code(304);
                rs.setMsg("查询结果为空！");
            }else { // 正常查到结果则将其 添加到 结果map
                rsMap.put("crsInfo", simpleCrsById);
            }
        }catch (Exception e){
            rs.setResult_code(303);
            rs.setMsg("数据库查询发生异常！ -- 滚动帖信息");
        }

        rsMap.put("rs", rs);
        return rsMap;
    }

    @Override
    public MessageModel updateCrsPostById(CarouselPost carouselPost, MultipartFile img, String path) {
        MessageModel rs = new MessageModel(200, "滚动帖信息修改成功！");
        int i;  /*文件名 小数点位置*/
        String fileType;  /*文件类型 包括.*/
        String saveName;  /*文件保存名*/
        String separator = File.separator; //定义分隔符
        Map<String, Object> map = new HashMap<>();  /*调用 mapper 层的 sql 参数map*/
        String originalImg; // 滚动帖原来设置的图片名称

        if (img.getSize() != 0){ /*用户重新选择了头像文件*/
            System.out.println("用户重新选择了滚动帖文件");
            try {
                /*将原头像删除*/
                originalImg = carouselMapper.getSimpleCrsById(carouselPost.getId()).getImages();
                if ( FileTool.deleteFile(path + separator + originalImg) == 0){
                    rs.setResult_code(409);
                    rs.setMsg("原图片删除失败！信息修改失败！");
                    return rs; //不更新数据库  直接返回
                }

                /*将新头像写入保存*/
                i = Objects.requireNonNull(img.getOriginalFilename()).lastIndexOf('.');
                fileType = img.getOriginalFilename().substring(i);  /*包括.*/
                fileType = fileType.toLowerCase(); //一律转小写
                saveName = carouselPost.getId() + fileType;  // 滚动帖 id  + 文件类型

                img.transferTo(new File(path + separator + saveName));
                map.put("img", saveName);
            } catch (IOException e) {
                rs.setResult_code(408);
                rs.setMsg("新图片写入失败！信息修改失败！");
                e.printStackTrace();
                System.out.println("新图片写入失败！信息修改失败！ -- 原图片 已被删除，请注意");
                return rs;  //不更新数据库  直接返回
            } catch (Exception e){
                rs.setResult_code(303);
                rs.setMsg("数据库查询发生异常!信息修改失败！-- 查询滚动帖信息失败");
                e.printStackTrace();
                return rs;
            }
        }

        /*更新数据库记录*/
        try {
            map.put("id", carouselPost.getId());
            map.put("postId", carouselPost.getPostId());
            map.put("describe", carouselPost.getDescribe());
            if (carouselMapper.updateCarousel(map) < 1){
                rs.setMsg("数据库记录更新失败！信息修改失败！");
                rs.setResult_code(302);
                System.out.println("数据库记录更新失败！信息修改失败！ -- 如果重新选择了图片文件，那图片文件已被修改");
            }
        }catch (Exception e){
            rs.setResult_code(303);
            rs.setMsg("数据更新发生异常!信息修改失败！-- 如果重新选择了图片文件，那图片文件已被修改");
            e.printStackTrace();
        }
        return rs;
    }

    @Override
    public MessageModel deleteCrsPostById(int id, String path) {
        MessageModel messageModel = new MessageModel(200, "滚动帖删除成功！");

        try {
            // 删除图片文件
            if (FileTool.deleteFile(path + carouselMapper.getSimpleCrsById(id).getImages()) == 0){
                messageModel.setResult_code(409);
                messageModel.setMsg("贴吧头像文件删除失败。删除失败");
                return messageModel;
            }

            // 删除数据库记录
            if (carouselMapper.deleteCrsPostById(id) < 1){ //删除记录受影响行数不为1
                messageModel.setResult_code(301);
                messageModel.setMsg("数据库删除失败。");
            }
        }catch (Exception e){
            messageModel.setResult_code(303);
            messageModel.setMsg("数据库删除发生异常!");
            e.printStackTrace();
        }

        return messageModel;
    }
}
